let socket;
let nowClick;
let nowChannel;
// let isVideo = false;
let peer;
let recall = false;
let micDevice = null;
// let selfVideoMedie;
let password;
let connection = [];
let nowstate = {
  state: false,
};
let loadVideo = true;
let isOpenVoice = true;
let isRealAudio = false;
let audioMedia = null;
let clickFn = "click";
let username = null;
let totalVolume = 1;
let whicthPlyear = null;
let processedTracks = new Set();
const postServeArray = [];
const postChannelArray = [];
const driver = new Driver();
const musicPath = {
  openmic: "./voice/openmic.MP3",
  closemic: "./voice/closemic.MP3",
  out: "./voice/out.MP3",
  openvoice: "./voice/openvoice.MP3",
  closevoice: "./voice/closevoice.MP3",
  join: "./voice/join.MP3",
};
// const speex = new Speex({
//   quality: 8, // 设置降噪的质量，通常在 0 到 10 之间，值越大降噪效果越好但也可能会损失音质
//   complexity: 3, // 设置降噪的复杂度，通常在 1 到 10 之间，值越大降噪效果越好但也可能会增加计算负载
// });
window.ipcRenderer.invoke("data-init").then((res) => {
  totalVolume = res.totalVolume;
  $(".change-volume input").val(totalVolume * 100);
  totalVolume === 0
    ? $(".voiceSwitch .line").addClass("line-animate")
    : $(".voiceSwitch .line").removeClass("line-animate");
  res.username && (username = res.username);
  isOpenVoice = res.isOpenVoice ? true : false;
});
const talkState = new Proxy(nowstate, {
  get(target, key) {
    return target[key];
  },
  set(target, key, value) {
    target[key] = value;
    value ? $(".chat").show() : $(".chat").hide();
    return true;
  },
});
function clearChannel(clickedElement) {
  // socket.disconnect();
  clickedElement.css({ color: "#919191" });
  clickedElement.data("state", false);
  clickedElement.find(".channel-main").html("");
}
const updataServerList = () => {
  window.ipcRenderer.invoke("updataServerList").then((res) => {
    let htmlContent = "";
    if (!res || res.length === 0) {
      htmlContent = `
      <p class="no-server center">暂时还没有服务器，快去<span onclick=addServer()>添加</span>吧</p>
      `;
      $(".main-left").html(htmlContent);
      return;
    }
    $.each(res, (indexInArray, valueOfElement) => {
      htmlContent += `
      <div class="main-left-single server-close" data-state="false"  data-password="${valueOfElement.password}"  data-server="${valueOfElement.ip}">
      <p class="server-title">${valueOfElement.name}</p>
      <div class="channel-main"></div>
  </div>
      `;
    });
    $(".main-left").html(htmlContent);
    if (!localStorage.getItem("first-time")) {
      const driver = new Driver({
        doneBtnText: "完毕",
        closeBtnText: "关闭",
        nextBtnText: "下一步",
        prevBtnText: "上一步",
        allowClose: false,
      });
      driver.defineSteps([
        {
          element: ".main-left",
          popover: {
            title: "服务器",
            description: "这里是您的服务器列表",
            position: "right",
          },
        },
        {
          element: ".main-left .main-left-single:first-child",
          popover: {
            title: "服务器",
            description: "这是您添加的服务器,左键进入",
            position: "right",
          },
        },
        {
          element: ".main-left",
          popover: {
            title: "个性化",
            description: "您可以在上方工具箱里,更改自己的名字",
            position: "right",
          },
        },
      ]);
      driver.start();
    }
    localStorage.setItem("first-time", true);
  });
};

function delPost(jqXHRRequests) {
  for (let i = jqXHRRequests.length - 1; i >= 0; i--) {
    let jqXHR = jqXHRRequests[i];
    if (jqXHR && jqXHR.readyState !== 4) {
      // 如果请求还未完成
      jqXHR.abort(); // 取消请求
      jqXHRRequests.splice(i, 1); // 从数组中移除已取消的请求
    }
  }
}

updataServerList();
const updataServerListChannel = new BroadcastChannel("updataServerList");
const updataChannelListsChannel = new BroadcastChannel("updataChannelLists");
const changeIsVoice = new BroadcastChannel("isOpenVoice");
const passwordInput = new BroadcastChannel("passwordInput");
const toolChannel = new BroadcastChannel("toolChannel");
toolChannel.addEventListener("message", (res) => {
  isOpenVoice = res.data.isOpenVoice;
  if (res.data.username !== username && res.data.username) {
    username = res.data.username;
    if (socket) {
      socket.emit("change-name", res.data.username);
    }
    $(".player").find(".self-color").text(res.data.username);
  }
});
changeIsVoice.addEventListener("message", (res) => (isOpenVoice = res));
passwordInput.addEventListener("message", (res) => {
  password = res.data;
  getPlayerList(nowChannel, password);
});
updataChannelListsChannel.addEventListener("message", (res) => {
  try {
    socket.emit("addChannel", res.data, (res) => {
      if (res.status) {
        window.ipcRenderer.send("connctError", [
          "error",
          "重复",
          "频道名字不能重复",
          ["ok"],
        ]);
      }
    });
  } catch (error) {
    window.ipcRenderer.send("connctError", [
      "error",
      "服务器错误",
      "服务器出现错误，请重试",
      ["ok"],
    ]);
  }
});
$(window).on("beforeunload", (e) => {
  leaveTheRoom();
});
const newChannel = (res) => {
  $(".no-server").hide();
  nowClick.find(".channel-main").append(`
  <div class="channel-title" data-state="false">
   <img style="transform: rotate(-90deg);" class="icon-row" src="./icon/down-row.png" alt="">
   <div>
       <p class="channel-name">${res.name}</p>
         <div class="player-all"></div>
   </div>
</div>
`);
};
updataServerListChannel.addEventListener("message", updataServerList);
$(".main-left").on(clickFn, async function (event) {
  let clickedElement = $(event.target);
  if (!clickedElement.hasClass("server-title")) return;
  clickedElement = clickedElement.parent();
  if (socket) leaveTheRoom();
  if (clickedElement.data("state") === true) {
    clearChannel(clickedElement);
    return;
  }
  if (clickedElement.find(".server-title img").length !== 0) return;
  clickedElement.siblings(".main-left-single").data("state", false);
  clickedElement.siblings(".main-left-single").css({
    color: "#919191",
  });
  clickedElement.siblings(".main-left-single").find(".channel-main").html("");
  clickedElement
    .siblings(".main-left-single")
    .find(".server-title img")
    .remove();
  //在这里添加load
  delPost(postServeArray);
  clickedElement.find(".server-title").append('<img src="./img/load.gif">');
  postServeArray.push(
    $.ajax(`${clickedElement.data("server")}/api/connect`, {
      type: "post",
      data: { password: clickedElement.data("password") },
      success: async (res) => {
        if (res.status) {
          clickedElement.find(".server-title img").remove();
          window.ipcRenderer.send("connctError", [
            "error",
            "连接失败",
            "服务器密码错误!",
            ["ok"],
          ]);
          return;
        }
        nowClick = clickedElement;
        if (socket) {
          socket.disconnect();
        }
        socket = await io(
          `${clickedElement.data("server")}?username=${username}`
        );
        initSocket(clickedElement);
        socket.emit("channelList", (res) => {
          const objectToMap = new Map(Object.entries(res));
          let htmlContent = "";
          if (!objectToMap.size) {
            htmlContent = `
          <p class="no-server">暂时还没有频道，快去<span onclick=addChannel()>创建</span>一个吧</p>
          `;
            clickedElement.find(".channel-main").html(htmlContent);
          }
          objectToMap.forEach((value, key) => {
            htmlContent += `
             <div class="channel-title" data-state="false">
              <img style="transform: rotate(-90deg);" class="icon-row" src="./icon/down-row.png" alt="">
              <div>
                  <p class="channel-name">${key}</p>
                    <div class="player-all"></div>
              </div>
          </div>
          `;
          });
          clickedElement.find(".channel-main").html(htmlContent);
          clickedElement.css({ color: "black" });
          clickedElement.data("state", true);
          clickedElement.find(".server-title img").remove();
        });
      },
      error: (textStatus) => {
        if (textStatus !== "abort") return;
        clickedElement.find(".server-title img").remove();
        clickedElement.data("state", false);
        clickedElement.css({ color: "#919191" });
        window.ipcRenderer.send("connctError", [
          "error",
          "错误",
          "服务器连接超时,请重试",
          ["ok"],
        ]);
      },
    })
  );
});

function initSocket() {
  if (!socket) return;
  socket.on("newChannel", (res) => {
    newChannel(res);
  });
  socket.on("disconnect", (err) => {
    console.log(err);
    console.log("离线");
  });
}

$(".main-left").on(clickFn, async function (event) {
  let clickedElement = $(event.target);
  if (
    !clickedElement.hasClass("channel-name") &&
    !clickedElement.hasClass("icon-row")
  )
    return;
  nowChannel = clickedElement.parents(".channel-title");
  if (nowChannel.find(".channel-name img").length !== 0) return;
  socket.removeAllListeners();
  init();
  reAnwser();
  initSocket(nowClick);
  if (clickedElement.parents(".channel-title").data("state")) {
    await leaveTheRoom();
    $(".chat-show").html("");
    clickedElement.parents(".channel-title").data("state", false);
    clickedElement.parents(".channel-title").find(".player-all").html("");
    clickedElement.parents(".channel-title").find(".icon-row").css({
      transform: "rotate(-90deg)",
    });
    return;
  }
  $(".chat-show").html("");
  const otherChannel = clickedElement.parents(".channel-title").siblings();
  otherChannel.data("state", false);
  otherChannel.find(".player-all").html("");
  otherChannel.find(".icon-row").css({
    transform: "rotate(-90deg)",
  });

  nowChannel.find(".channel-name").append('<img src="./img/load.gif">');
  getPlayerList(nowChannel);
  // socket.on('delPeople', (id) => {
  //   $(`.video-single[data-id="${id}"]`).remove()
  // })
  socket.on("change-name", (res) => {
    $(`.player[data-id=${res.id}]`).find("p").text(res.username);
    $(`.video-single[data-id=${res.id}]`).find("p").text(res.username);
  });
  socket.on("userJoined", (res) => {
    addPlayer(clickedElement.siblings(".player-all"), res);
  });
  socket.on("userLeft", (res) => {
    playMusic(musicPath.out);
    delPlayer(clickedElement.siblings(".player-all").find(".player"), res);
    $(`.video-single[data-id="${res}"]`).remove();
  });
});

function addServer() {
  window.ipcRenderer.send("addServer");
}
function addChannel() {
  window.ipcRenderer.send("addChannel");
}

function addWebRTCConnect(peerConnectionSingle) {
  // 应用音频处理选项
  // const options = {
  //   noiseSuppression: true,
  //   echoCancellation: true,
  //   autoGainControl: true,
  //   voiceActivityDetection: true,
  //   applyConstraints: true,
  // };
  // peerConnectionSingle.getSenders().forEach((sender) => {
  //   if (sender.track.kind === "audio") {
  //     sender.track.applyConstraints(options);
  //   }
  // });
  connection.push(peerConnectionSingle);
}

function playMusic(path) {
  if (isOpenVoice) {
    const music = new Audio(path);
    music.volume = 0.2;
    music.play();
  }
}

async function getPlayerList(clickedElement, password = null) {
  await leaveTheRoom();
  let urlString = clickedElement.parents(".main-left-single").data("server");
  const url = new URL(urlString);
  const hostname = url.hostname;
  const port = url.port;
  const trun = await $.ajax(
    `${clickedElement.parents(".main-left-single").data("server")}/api/turn`,
    {
      type: "post",
      data: {
        password: clickedElement.parents(".main-left-single").data("password"),
      },
    }
  );
  const { urls, username, credential } = trun.message;
  const trunConfig = {
    urls,
    username,
    credential,
  };
  const iceServers = [
    { urls: "stun:stun.l.google.com:19302" }, // STUN 服务器
  ];
  (urls && username && credential) ? iceServers.push(trunConfig) : iceServers.length = 0; // TURN 服务器
  console.log(iceServers);
  peer = new Peer({
    host: hostname,
    port,
    path: "/",
    pingInterval: 5000,
    config: {
      iceServers,
    },
  });
  peer.on("error", (error) => {
    console.log("peer出现错误", error);
  });

  socket.on("video-show", (mes) => {
    mes.isVideo
      ? $(`.video-single[data-id=${mes.id}]`).appendTo(".video-here")
      : $(`.video-single[data-id=${mes.id}]`).appendTo(".audio-video");
    if (mes.isVideo) {
      $(`.video-single[data-id=${mes.id}]`)
        .find(".video")[0]
        .srcObject.getVideoTracks()[0].enabled = true;
    }
    $(".video-here").find(".video-single").length === 0
      ? moveChatDom(false)
      : moveChatDom(true);
  });

  peer.on("call", function (call) {
    console.log("回应电话", audioMedia.getTracks());
    call.answer(audioMedia);
    // socket.emit(
    //   "anwser",
    //   call.metadata.id,
    //   audioMedia.getVideoTracks()[0] instanceof CanvasCaptureMediaStreamTrack,
    //   () => {
    //     call.answer(audioMedia);
    //   }
    // );
    call.on("stream", async function (stream) {
      const tracks = stream.getTracks();
      for (let i = 0; i < tracks.length; i++) {
        if (processedTracks.has(tracks[i].id)) return;
        processedTracks.add(tracks[i].id);
      }
      let username = "没有这个用户";
      socket.emit("getName", call.metadata.id, (name) => {
        username = name;

        addWebRTCConnect(call.peerConnection);
        // console.log("是否为真实video", call.metadata.isVirturlVideo);
        if (call.metadata.isVirturlVideo) {
          stream.getVideoTracks()[0] &&
            (stream.getVideoTracks()[0].enabled = false);
        } else {
          stream.getVideoTracks()[0] &&
            (stream.getVideoTracks()[0].enabled = true);
        }
        playMusic(musicPath.join);
        // moveChatDom(stream.getVideoTracks().length != 0);
        console.log("收到stream", stream.getTracks());

        // if (call.metadata.recall) {
        // const videoContainer = $(
        //   `.video-single[data-id="${call.metadata.id}"]`
        // );
        // const videoDom = $(`.video-single[data-id="${call.metadata.id}"]`).find(
        //   ".video"
        // )[0];
        // if ($(videoContainer).parent().hasClass("audio-video") && isVideo) {
        //   videoContainer.prependTo(".video-here");
        // }
        // if ($(videoContainer).parent().hasClass("video-here") && !isVideo) {
        //   videoContainer.prependTo(".audio-video");
        // }
        // videoDom.srcObject = stream;
        // if ($(".voiceSwitch").find(".line").hasClass("line-animate")) {
        //   videoDom.muted = true;
        // }
        // videoDom.play();
        // } else {
        $(".audio-video").append(`
      <div class="video-single" data-volume="1" data-id="${call.metadata.id}">
      <video class="video"></video>
      <p>${username}</p>
      </div>
      `);
        $(".video:last")[0].srcObject = stream;
        if ($(".voiceSwitch").find(".line").hasClass("line-animate")) {
          // $(".video:last")[0].muted = true;
          changeVolume(".video:last", 0);
        } else {
          changeVolume(".video:last");
        }
        $(".video:last")[0].play();
        // }
      });
    });
  });

  peer.on("open", function (id) {
    console.log("peer连接成功");
    socket.emit(
      "playerList",
      {
        name: clickedElement.find(".channel-name").text(),
        password,
        peerId: peer.id,
        recall,
      },
      async (res) => {
        if (res.status === 1) {
          window.ipcRenderer.send("connctError", [
            "error",
            "连接失败",
            "找不到频道,请删除重试",
            ["ok"],
          ]);
          return;
        }
        if (res.status === 2) {
          window.ipcRenderer.send("passwordInput");
          return;
        }
        if (res.status === 3) {
          window.ipcRenderer.send("connctError", [
            "error",
            "进入失败",
            "密码错误",
            ["ok"],
          ]);
          return;
        }
        socket.on("receive-message", (res) => {
          $(".chat-show").append(`
        <div class="chat-single">
        <div>
            <p class="chat-player ${
              res.id === socket.id ? "self-color" : ""
            }">${res.name}:</p>
            <p class="chat-content">${res.message}</p>
        </div>
            <p>${getTime()}</p>
        </div>
        `);
          scrollToBottom($(".chat-video")[0]);
          scrollToBottom($(".main-right")[0]);
        });
        talkState.state = true;
        await clickedElement.data("state", true);
        $(".nobody-chat p").text(
          `${clickedElement
            .parents(".main-left-single")
            .find(".server-title")
            .text()} -> ${clickedElement.text()}`
        );
        clickedElement.find(".icon-row").css({
          transform: "rotate(0deg)",
        });
        await getAudio();
        let htmlContent = "";
        $(".video-single").remove();
        res.message.forEach((item) => {
          if (item.id !== socket.id) {
            let data = {
              recall,
              id: socket.id,
              isVirturlVideo:
                audioMedia.getVideoTracks()[0] instanceof
                CanvasCaptureMediaStreamTrack,
            };
            console.log("打电话出去");
            let conn = peer.call(item.peerId, audioMedia, { metadata: data });
            addWebRTCConnect(conn.peerConnection);
            // let isCanvas = false;
            // socket.on("recive", (canvas, fn) => {
            //   isCanvas = canvas;
            //   fn();
            // });
            conn.on("stream", (remoteStream) => {
              // remoteStream.getVideoTracks().forEach((track) => {
              // if (isCanvas) {
              //   track.stop();
              //   remoteStream.removeTrack(track);
              // }
              // });
              const tracks = remoteStream.getTracks();
              for (let i = 0; i < tracks.length; i++) {
                if (processedTracks.has(tracks[i].id)) return;
                processedTracks.add(tracks[i].id);
              }
              console.log("对方回应并返回", remoteStream.getTracks());
              if (!item.isVideo) {
                remoteStream.getVideoTracks()[0] &&
                  (remoteStream.getVideoTracks()[0].enabled = false);
              } else {
                remoteStream.getVideoTracks()[0] &&
                  (remoteStream.getVideoTracks()[0].enabled = true);
                moveChatDom(true);
              }
              $(item.isVideo ? ".video-here" : ".audio-video").append(`
            <div class="video-single" data-volume="1" data-id="${item.id}">
            <video class="video"></video>
            <p>${item.name}</p>
            </div>
            `);
              $(".video:last")[0].srcObject = remoteStream;
              if ($(".voiceSwitch").find(".line").hasClass("line-animate")) {
                changeVolume(".video:last", 0);
              } else {
                changeVolume(".video:last");
              }
              $(".video:last")[0].play();
            });
          }
          htmlContent += `
          <div class="player" data-id="${item.id}">
            <img class="icon-big" src="./icon/player-online.png" alt="">
            <p class="${item.id === socket.id ? "self-color" : ""}">${
            item.name
          }</p>
          </div>
          `;
        });
        recall = false;
        clickedElement.find(".player-all").html(htmlContent);
        clickedElement.find(".channel-name img").remove();
      }
    );
  });
}

function addPlayer(clickedElement, info) {
  clickedElement.append(`
  <div class="player" data-id="${info.id}">
    <img class="icon-big" src="./icon/player-online.png" alt="">
    <p>${info.name}</p>
  </div>
  `);
}

function delPlayer(clickedElement, id) {
  // clickedElement.find(".player").=== true;
  clickedElement.each(function (index, dom) {
    if ($(dom).data("id") === id) $(dom).remove();
  });
}

async function leaveTheRoom() {
  if (audioMedia) {
    audioMedia.getTracks().forEach((track) => {
      track.stop();
      audioMedia.removeTrack(track);
    });
  }
  if (peer) {
    await peer.disconnect();
    await peer.destroy();
  }
  if (connection) connection = [];
  init();
  $(".video-single").remove();
  talkState.state = false;
  $(".nobody-chat p").text(`暂时没有加入频道`);
  if (socket) {
    await socket.emit("leaveRoom");
  }
}

function init() {
  $(".self-video").parent().remove();
  $(".videoSwitch").find(".line").addClass("line-animate");
}
let messageState = true;
function sendMessage() {
  if (!messageState) return;
  messageState = false;
  if (!$(".chat-input").val().trim()) {
    window.ipcRenderer.send("connctError", [
      "error",
      "请重试",
      "请输入文字",
      ["ok"],
    ]);
    messageState = true;
    return;
  }
  socket.emit("send-message", $(".chat-input").val(), (res) => {
    $(".chat-input").val("");
    messageState = true;
    if (!res.status) return;
    window.ipcRenderer.send("connctError", [
      "error",
      "出现错误",
      "频道获取失败,请重新进入",
      ["ok"],
    ]);
  });
}

async function getAudio() {
  const audioConfig = {
    noiseSuppression: true,
    echoCancellation: true,
    // autoGainControl: true,
    voiceActivityDetection: true,
    applyConstraints: true,
    sampleRate: 48000,
    volume: 0,
    latency: 8000,
    channelCount: 2
  };
  micDevice ? (audioConfig.deviceId = micDevice) : 1;
  await navigator.mediaDevices
    .getUserMedia({
      audio: audioConfig,
    })
    .then((midea) => {
      const audioContext = new AudioContext();
      const source = audioContext.createMediaStreamSource(midea);

      // 创建高通滤波器，去除低频噪声（如风扇声音）
      const highpassFilter = audioContext.createBiquadFilter();
      highpassFilter.type = "highpass";
      highpassFilter.frequency.value = 200; // 设置一个合适的截止频率，例如200Hz

      // 创建低通滤波器，去除高频噪声（如键盘和鼠标声音）
      const lowpassFilter = audioContext.createBiquadFilter();
      lowpassFilter.type = "lowpass";
      lowpassFilter.frequency.value = 500; // 设置一个合适的截止频率，例如4000Hz

      // 可选：创建噪声门，减少静默期间的噪声
      const noiseGate = audioContext.createGain();
      noiseGate.gain.value = 1000; // 初始设置为静音
      // // 根据需要动态调整噪声门的阈值和开启/关闭时间
      // 将源节点连接到高通滤波器
      source.connect(highpassFilter);
      // 将高通滤波器连接到低通滤波器
      highpassFilter.connect(lowpassFilter);
      // 可选：将低通滤波器连接到噪声门
      lowpassFilter.connect(noiseGate);
      // 创建MediaStreamDestination对象
      const destination = audioContext.createMediaStreamDestination();
      // 将最后一个节点（可能是低通滤波器或噪声门）连接到目的地
      lowpassFilter.connect(destination);
      // 获取新的音频流
      const outputStream = destination.stream;

      if (audioMedia) {
        audioMedia.getAudioTracks().forEach((track) => {
          track.stop();
          audioMedia.removeTrack(track);
        });
        outputStream.getAudioTracks().forEach((track) => {
          audioMedia.addTrack(track);
        });
      } else {
        audioMedia = outputStream;
      }
      if (audioMedia.getVideoTracks().length === 0) {
        getVirtualVdieo();
      }
      isRealAudio = true;
      $(".micSwitch").find(".line").removeClass("line-animate");
    })
    .catch((error) => {
      console.log(error);
      getVirtualDevice();
      if (audioMedia.getVideoTracks().length === 0) {
        getVirtualVdieo();
      }
      isRealAudio = false;
    });
}
function getVirtualVdieo() {
  let canvas = document.createElement("canvas");
  // canvas.width = 0;
  // canvas.height = 0;
  // var ctx = canvas.getContext("2d");
  // ctx.fillStyle = "#FF0000";
  // ctx.fillRect(0, 0, canvas.width, canvas.height);
  audioMedia.getVideoTracks().forEach((t) => {
    t.stop();
    audioMedia.removeTrack(t);
  });
  audioMedia.addTrack(canvas.captureStream().getTracks()[0]);
}

function reAnwser() {
  socket.on("re-offer", (offer) => {
    console.log("收到offer", offer);
    const remoteDesc = new RTCSessionDescription(offer);
    connection.forEach(async (connect) => {
      connect.setRemoteDescription(remoteDesc);
      let answer = await connect.createAnswer();
      connect.setLocalDescription(answer);
      socket.emit("re-anwser", answer);
    });
  });

  socket.on("re-anwser", async (answer) => {
    console.log("收到anwser", answer);
    connection.forEach(async (connect) => {
      await connect.setRemoteDescription(answer);
    });
  });
}

async function getVideo(open) {
  if (open) {
    await navigator.mediaDevices
      .getUserMedia({
        video: true,
      })
      .then(async (midea) => {
        audioMedia.getVideoTracks().forEach((track) => {
          track.stop();
          audioMedia.removeTrack(track);
        });
        midea.getTracks().forEach((track) => {
          audioMedia.addTrack(track);
        });
        $(".videoSwitch").find(".line").removeClass("line-animate");
        // connection.forEach((connec) => {
        //   connec.getSenders().forEach((sender) => {
        //     if (sender.track && sender.track.kind === "video") {
        //       sender.replaceTrack(audioMedia.getVideoTracks()[0]);
        //     }
        //   });
        //   connec.addTrack(audioMedia.getVideoTracks()[0], audioMedia);
        //   connec.createOffer().then((offer) => {
        //     connec.setLocalDescription(offer);
        //     socket.emit("re-offer", offer);
        //   });
        // });
        await toreCall("video", audioMedia.getVideoTracks()[0]);
        moveChatDom(true);
        socket.emit("video-show", true);
        $(".video-here").append(`
          <div class="video-single" data-volume="1">
          <video class="self-video"></video>
          <p class="self-color">自己</p>
          </div>
          `);
        // selfVideoMedie = new MediaStream()
        // audioMedia.getVideoTracks().forEach((track) => {
        //   selfVideoMedie.addTrack(track)
        // })
        $(".self-video")[0].srcObject = audioMedia;
        $(".self-video")[0].muted = true;
        $(".self-video")[0].play();
        loadVideo = true;
        // connectiong.onicecandidate = function (event) {
        //   if (event.candidate) {
        //     // 发送ICE候选到远端对等方
        //     socket.emit("ice-candidate", event.candidate);
        //   } else {
        //     // 所有ICE候选信息已经收集完毕
        //     console.log("All ICE candidates have been gathered");
        //   }
        // };
        // await peer.disconnect();
        // await peer.reconnect();
        // await toreCall("video", audioMedia.getVideoTracks()[0]);
      })
      .catch((error) => {
        console.log(error);
        loadVideo = true;
        $(".videoSwitch").find(".line").addClass("line-animate");
        window.ipcRenderer.send("connctError", [
          "error",
          "出现错误",
          "没有找到摄像头,请重试",
          ["ok"],
        ]);
      });
  } else {
    audioMedia.getVideoTracks().forEach((track) => {
      track.stop();
      audioMedia.removeTrack(track);
    });
    getVirtualVdieo();
    await toreCall("video", audioMedia.getVideoTracks()[0]);
    socket.emit("video-show", false);
    $(".videoSwitch").find(".line").addClass("line-animate");
    $(".self-video")[0].pause();
    $(".self-video").parent().remove();
    loadVideo = true;
    // recall = true;
    // await peer.disconnect();
    // await peer.reconnect();
    // toreCall("video", audioMedia.getVideoTracks()[0]);
  }
}

function getVirtualDevice() {
  getDeviceError();
  $(".micSwitch").find(".line").addClass("line-animate");
  // 创建音频上下文
  const audioContext = new AudioContext();
  // 创建虚拟的媒体流目标
  const mediaStreamDestination = audioContext.createMediaStreamDestination();
  // 获取虚拟轨道的音频轨道
  const mediaStreamTrack = mediaStreamDestination.stream.getAudioTracks()[0];
  if (audioMedia) {
    audioMedia.getAudioTracks((t) => {
      t.stop();
      audioMedia.remove(t);
    });
  } else {
    audioMedia = new MediaStream();
  }
  audioMedia.addTrack(mediaStreamTrack);
}

$(".sendBtn").on("click", sendMessage);

$(".chat-input").on("keypress", function (event) {
  if (event.which === 13 && !event.shiftKey) {
    // 按下回车键且没有同时按下 Shift 键
    // event.preventDefault();
    sendMessage(); // 执行你想要的操作，例如发送消息
  }
});

function getTime() {
  const currentDate = new Date();
  const year = currentDate.getFullYear(); // 获取当前年份
  const month = currentDate.getMonth() + 1; // 获取当前月份（注意月份是从 0 开始计数的，所以要加 1）
  const day = currentDate.getDate(); // 获取当前日期
  const hours = currentDate.getHours(); // 获取当前小时
  const minutes = currentDate.getMinutes(); // 获取当前分钟
  const seconds = currentDate.getSeconds(); // 获取当前秒数

  // 格式化时间，保证每个部分都是两位数
  const formattedDate = `${year}-${month.toString().padStart(2, "0")}-${day
    .toString()
    .padStart(2, "0")}`;
  const formattedTime = `${hours.toString().padStart(2, "0")}:${minutes
    .toString()
    .padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`;

  return `${formattedDate} ${formattedTime}`;
}

function scrollToBottom(dom) {
  dom.scrollTop = dom.scrollHeight;
}

$(".chat-animal").on("click", async (event) => {
  if (
    !$(event.target).hasClass("inputImg") &&
    !$(event.target).hasClass("line")
  )
    return;
  clickedElement = $(event.target).hasClass("inputImg")
    ? $(event.target).siblings(".line")
    : $(event.target);
  clickedElement.hasClass("line-animate")
    ? clickedElement.removeClass("line-animate")
    : clickedElement.addClass("line-animate");
  clickedElement.parent().hasClass("videoSwitch") &&
    (await videoSwitch(!clickedElement.hasClass("line-animate")));
  clickedElement.parent().hasClass("voiceSwitch") &&
    voiceSwitch(!clickedElement.hasClass("line-animate"));
  if (clickedElement.parent().hasClass("micSwitch")) {
    !isRealAudio
      ? getDeviceError()
      : micSwitch(!clickedElement.hasClass("line-animate"));
    !isRealAudio && clickedElement.addClass("line-animate");
  }
});
$(".chat-animal").on("contextmenu", (event) => {
  event.preventDefault();
  clickedElement = $(event.target);
  clickedElement.parent().hasClass("micSwitch") && getDevice("audioinput");
});

async function getDevice(which) {
  let template = [];
  navigator.mediaDevices
    .enumerateDevices()
    .then(async (device) => {
      if (which === "audioinput") {
        for (let i = 0; i < device.length; i++) {
          if (device[i].kind !== "audioinput") continue;
          item = device[i];
          if (item.deviceId === "default") {
            template.push({ label: "默认设备-跟随系统", id: item.deviceId });
          } else {
            const stream = await navigator.mediaDevices.getUserMedia({
              audio: { deviceId: item.deviceId },
            });
            stream.getTracks().forEach((track) => {
              track.stop();
              stream.removeTrack(track);
            });
            template.push({
              label: item.label,
              id: item.deviceId,
            });
          }
        }
      } else if (which === "audiooutput") {
        device.forEach((item) => {
          template.push({
            label: item.label,
            id: item.deviceId,
          });
        });
      }
    })
    .catch((error) => {
      template = [
        {
          label: "没有找到任何设备",
          id: "error",
        },
      ];
    })
    .finally(() => {
      window.ipcRenderer.send("devidceGet", template);
    });
}
window.ipcRenderer.on("deviceSelected", async (selectedDeviceId) => {
  micDevice = selectedDeviceId;
  audioMedia.getAudioTracks().forEach((track) => {
    track.stop();
    audioMedia.removeTrack(track);
  });
  await getAudio();
  toreCall("audio", audioMedia.getAudioTracks()[0]);
});

async function toreCall(type = "audio", mediaTrack) {
  // recall = true;
  // await peer.disconnect();
  // await peer.reconnect();
  // await peer.destroy();
  // getPlayerList(nowChannel, password);
  if (connection.length === 0) return;
  connection.forEach((connect) => {
    connect.getSenders().forEach((s) => {
      if (s.transport.state !== "closed" && s.track.kind === type)
        s.replaceTrack(mediaTrack);
    });
  });
}

async function videoSwitch(isOff) {
  if (!loadVideo) return;
  loadVideo = false;
  await getVideo(isOff);
}
function moveChatDom(isOff) {
  if (isOff) {
    $(".chat-video").show();
    $(".chat-show").appendTo(".chat-video");
    scrollToBottom($(".chat-video")[0]);
  } else {
    $(".chat-video").hide();
    $(".chat-show").appendTo(".chat-here");
  }
}
async function micSwitch(isOff) {
  if (isOpenVoice) {
    isOff ? playMusic(musicPath.openmic) : playMusic(musicPath.closemic);
  }
  if (!audioMedia) return;
  const audioTracks = audioMedia.getAudioTracks();
  if (isOff) {
    audioTracks.forEach((track) => (track.enabled = true));
    return;
  }
  audioTracks.forEach((track) => (track.enabled = false));
}
function voiceSwitch(isOff) {
  if (isOpenVoice) {
    isOff ? playMusic(musicPath.openvoice) : playMusic(musicPath.closevoice);
  }
  if (!isOff) {
    // $(".video").each((index, dom) => {
    //    dom.muted = true;
    // });
    changeVolume("video", 0);
    $(".change-volume input").val(0);
  } else {
    // $(".video").each((index, dom) => {
    //   dom.muted = false;
    // });
    totalVolume = totalVolume === 0 ? 0.2 : totalVolume;
    changeVolume("video");
    $(".change-volume input").val(totalVolume * 100);
  }
}
// function deviceOn(jqDom) {
//   jqDom.find(".line").removeClass("line-animate");
// }

function getDeviceError() {
  window.ipcRenderer.send("connctError", [
    "error",
    "获取失败",
    "麦克风不可用,请选择其他麦克风设备",
    ["ok"],
  ]);
}

$(".main-left").on("contextmenu", (event) => {
  event.preventDefault();
  clickedElement = $(event.target);
  if (!clickedElement.hasClass("server-title")) return;
  const data = {
    whitch: clickedElement.parent(".main-left-single").data("server"),
    state: clickedElement.parent(".main-left-single").data("state"),
  };
  window.ipcRenderer.send("serveMenu", data);
});
$(".main-left").on("contextmenu", (event) => {
  event.preventDefault();
  clickedElement = $(event.target);
  if (!clickedElement.parent().hasClass("player")) return;
  if (
    clickedElement.hasClass("self-color") ||
    clickedElement.siblings().hasClass("self-color")
  )
    return;
  const text = clickedElement.parent().find("p");
  $(".player-volume").hide();
  $(".player-volume").css({
    top: text.offset().top + "px",
    left: text.offset().left + "px",
  });
  whicthPlyear = clickedElement.parent().data("id");
  $(".player-volume input").val(
    $(`.video-single[data-id="${whicthPlyear}"]`).data("volume") * 100
  );
  $(".player-volume").show();
  $(window).on("contextmenu", hideContextMenu);
  $(window).on("click", hideContextMenu);
});

$(".player-volume").on("change", (e) => {
  if (!whicthPlyear) return;
  $(`.video-single[data-id="${whicthPlyear}"]`).data(
    "volume",
    e.target.value / 100
  );
  changeVolume($(`.video-single[data-id="${whicthPlyear}"]`).find("video"));
});

function hideContextMenu(e) {
  clickedElement = $(e.target);
  if (
    clickedElement.parent().hasClass("player-volume") ||
    clickedElement.parent().hasClass("player")
  )
    return;
  $(".player-volume").hide();
  $(window).off("contextmenu", hideContextMenu);
  $(window).off("click", hideContextMenu);
}

window.ipcRenderer.on("serverListUpdata", (ip) => {
  if (
    nowClick &&
    nowClick.parents(".main-left-single")[0] ===
      $(`.main-left-single[data-server="${ip}"]`)[0]
  ) {
    leaveTheRoom();
  }
  $(`.main-left-single[data-server="${ip}"]`).remove();
  if ($(`.main-left-single`).length === 0) {
    let htmlContent = `
  <p class="no-server center">暂时还没有服务器，快去<span onclick=addServer()>添加</span>吧</p>
  `;
    $(".main-left").html(htmlContent);
  }
});
window.ipcRenderer.on("voice-swich", () => {
  if (!peer) return;
  jqDom = $(".voiceSwitch").find(".line");
  voiceSwitch(jqDom.hasClass("line-animate"));
  jqDom.toggleClass("line-animate");
});
window.ipcRenderer.on("mic-swich", () => {
  if (!peer) return;
  const jqDom = $(".micSwitch").find(".line");
  micSwitch(jqDom.hasClass("line-animate"));
  jqDom.toggleClass("line-animate");
});
$(".chat-animal .change-volume").on("change", (event) => {
  totalVolume = event.target.value / 100;
  totalVolume === 0
    ? $(".voiceSwitch .line").addClass("line-animate")
    : $(".voiceSwitch .line").removeClass("line-animate");
  window.ipcRenderer.send("change-volume", totalVolume);
  changeVolume("video");
});
function changeVolume(dom, num = totalVolume) {
  $(dom).each(function () {
    $(this).prop("volume", num * $(this).parent().data("volume"));
  });
}

/**
 * 测试输出设备是否真实(暂时不启用)
 * 
 * async function testMicrophone(deviceId) {
  try {
    const constraints = { audio: { deviceId: { exact: deviceId } }, video: false };
    const stream = await navigator.mediaDevices.getUserMedia(constraints);

    创建AudioContext实例
    const audioContext = new (window.AudioContext || window.webkitAudioContext)();
    const source = audioContext.createMediaStreamSource(stream);
    const analyser = audioContext.createAnalyser();

    连接音频源到分析器
    source.connect(analyser);

    设置分析器的 fftSize 和 smoothingTimeConstant
    analyser.fftSize = 2048;
    analyser.smoothingTimeConstant = 0.3;

    获取频率数据
    const frequencyData = new Uint8Array(analyser.frequencyBinCount);
    
    简单的音频活动检测
    setTimeout(async () => {
      analyser.getByteFrequencyData(frequencyData);
      const hasActivity = frequencyData.some(value => value > 50); // 简化的阈值，根据实际情况调整
      
      console.log(hasActivity ? "麦克风检测到音频活动，可能是真实设备." : "未检测到明显的音频活动。");

     清理
      source.disconnect();
      analyser.disconnect();
      stream.getTracks().forEach(track => track.stop());
    }, 6000); 
  等待一段时间以收集音频数据，时间根据需要调整

  } catch (error) {
    console.error("测试麦克风时出错:", error);
  }
}

 使用设备ID调用测试函数
 例如，deviceId为从enumerateDevices获取的某个麦克风的deviceId
 testMicrophone('your_device_id_here');
 * 
 * 
 * 
 * 
 */
